#__docformat__ = "restructuredtext en"
# ******NOTICE***************
# dataclass.py module by Shoibal Chakravarty
#
# You may copy and use this module as you see fit with no
# guarantee implied provided you keep this notice in all copies.
# *****END NOTICE************
"""
This module contains the functions that solve the reference Myopic 
scenario where the three regions deploy new green investment in the current
period based on the last period's cost of green energy only.
"""

__author__ = "Shoibal Chakravarty (shoibalc@princeton.edu)"
__version__ = "0.1"
__date__ = "2011/August"
__license__ = "BSD"
__all__ = ['threemyopic','myopicupdate','regionupdate','worldupdate','cumulativecost']
import numpy as np
from dataops import cg2



###### 1 PERIOD MODEL #####################
# ga1, ma1, ua1, fa1, Ga1, Fa1, gb1,mb1, ub1, fb1, Gb1, Fb1, g, G, cgt = OnePeriodmodel(Ga0, Gb0)
def threemyopic(r1,r2,r3,w,com):
    """
    Function threemyopic solves the myopic deployment case for the three regions
    r1, r2, r3 (instances of the region class) and returns updated r's and w, an 
    instance of the world class.
    """
    r1.descriptor = r2.descriptor = r3.descriptor = 'Myopic'
    for t in range(w.T):
        r1.g[t], r1.u1[t], r1.c1[t], r1.m[t] = myopicupdate(r1,r2,r3,w,t)
        regionupdate(r1,t)
        r2.g[t], r2.u1[t], r2.c1[t], r2.m[t] = myopicupdate(r2,r3,r1,w,t)
        regionupdate(r2,t)
        r3.g[t], r3.u1[t], r3.c1[t], r3.m[t] = myopicupdate(r3,r1,r2,w,t)
        regionupdate(r3,t)
        worldupdate(r1,r2,r3,w,com,t)
    cumulativecost(r1,r2,r3,w)

def myopicupdate(r,rb,rc,w,t):
    """
    Function myopicupdate solves the current period green energy deployment
    problem for region r based on the last period's cost of green energy. myopicupdate
    returns the following for the current period:\n\n
    (incremental green energy, utility, incremental subsidy cost, maximum allowed green energy)
    """
    Bx=r.B[t]
    cnx=r.cn[t]
    cox=r.co[t]
    cgx=w.cg[t]
    Gx=r.G[t]
    Gy=rb.G[t]+rc.G[t]
    ex=r.e[t]
    Ex=r.E[t+1]
    M = r.M[t]
    mt = min(M*Ex,(Ex - Gx))
    greturn, ureturn, creturn  = 0.0, 0.0, 0.0
    Gt = Gx + Gy
###    cg = cgx*(Gt/G0)^alpha
#    cg = cg2(G0,Gt)
    cgn = cgx - cnx
    cgo = cgx - cox
    g1  = Bx/cgn - 1.0
    g2  = Bx/cgo - 1.0
    
    if mt < ex-0.00001:
        print mt,ex,Gt,Ex,Gy,Gx
        raise ValueError('Max deployment should be greater than next period net demand. Check your assumptions!\n')
    if Bx >= cgn:
        if cgn > 0.0:
            if g1 < ex:
                greturn = g1
                creturn = greturn*cgn 
                ureturn = Bx*np.log(1.0 + greturn) - creturn
            elif g1 > ex and g2 < ex:
                greturn = ex 
                creturn = greturn*cgn
                ureturn = Bx*np.log(1.0 + greturn) - creturn
            elif g2 > ex and g2 <= mt:
                greturn = g2
                creturn = (greturn-ex)*cgo + ex*cgn
                ureturn = Bx*np.log(1.0 + greturn) - creturn
            elif g2 > mt:
                greturn = mt
                creturn = (greturn-ex)*cgo + ex*cgn
                ureturn = Bx*np.log(1.0 + greturn) - creturn
            else:
                raise ValueError("nextgG something wrong! cgn > 0.0: you should never reach here!\n")
#            print "cg", cg, "g", greturn, "u", ureturn, "c", creturn, "g1",g1, "g2", g2,"e", ex, "m", mt
            return greturn, ureturn, creturn, mt
        elif cgn <= 0.0 and cgo > 0.0:
            if  g2 < ex:
                greturn = ex
                creturn = 0.0
                ureturn = Bx*np.log(1.0 + greturn)
            elif g2 > ex and g2 <= mt:
                greturn = g2
                creturn = (greturn-ex)*cgo
                ureturn = Bx*np.log(1.0 + greturn) - creturn
            elif g2 > mt:
                greturn = mt
                creturn = (greturn-ex)*cgo
                ureturn = Bx*np.log(1.0 + greturn) - creturn
            else:
                raise ValueError("nextgG something wrong! cgo > 0.0: you should never reach here!\n")
#            print "cg", cg, "g", greturn, "u", ureturn, "c", creturn, "g1",g1, "g2", g2,"e", ex, "m", mt
            return greturn, ureturn, creturn, mt
        elif cgo <= 0.0:
            greturn = mt
            creturn = 0.0
            ureturn = Bx*np.log(1.0 + greturn)
#            print "cg", cg, "g", greturn, "u", ureturn, "c", creturn, "g1",g1, "g2", g2,"e", ex, "m", mt
            return greturn, ureturn, creturn, mt
        else:
            raise ValueError("nextgG something wrong! cgn > 0.0: you should never reach here!\n")
    elif Bx < cgn:
        greturn = 0.0
        ureturn = 0.0
        creturn = 0.0
#        print "cg", cg, "g", greturn, "u", ureturn, "c", creturn, "g1", g1, "g2", g2,"e", ex, "m", mt
        return greturn, ureturn, creturn, mt
    else:
        raise ValueError("nextgG something wrong! you should never reach here!\n")

def regionupdate(r,t):
    """
    Function regionupdate is a utility function that stores the current period results
    after a call to myopicupdate.
    """
    r.f[t] = r.e[t] - r.g[t]
    r.F[t+1] = r.F[t] + r.f[t]
    r.G[t+1] = r.G[t] + r.g[t]

def cumulativecost(r1,r2,r3,w):
    """
    Function cumulativecost  calculates the total regional and global green
    energy subsidy in the current period.
    """
    r1.C1 = r1.c1.cumsum()
    r2.C1 = r2.c1.cumsum()
    r3.C1 = r3.c1.cumsum()
    w.C1 = w.c1.cumsum()


def worldupdate(r1,r2,r3,w,com,t):
    """
    Function worldupdate is an utility function that calculates and stores 
    the current period world results after the current period regional green 
    energy deployment problem is solved.
    """
    w.g[t] = r1.g[t] + r2.g[t] + r3.g[t]
    w.f[t] = w.e[t] - w.g[t]
    w.G[t+1] = w.G[t] + w.g[t]
    w.F[t+1] = w.F[t] + w.f[t]
    w.cg[t+1] = cg2(com.cg0,w.G[0],w.G[t+1],com.greenpar)
    w.u1[t] = r1.u1[t] + r2.u1[t] + r3.u1[t]
    w.c1[t] = r1.c1[t] + r2.c1[t] + r3.c1[t]
    w.GS[t+1] = w.G[t+1]/w.E[t+1]
    

